#!/usr/bin/env python
# encoding: utf-8
# @author: Lin Han
# @contact: voldemort22@126.com
# @file: app.py
# @time: 2021/6/10 16:26
# @desc:
import json

from fastapi import APIRouter, Request, BackgroundTasks

from application.history_clamp.crud import get_history_clamp_in_assigned_scene, get_standard_clamp_by_history_clamp
from application.scene.crud import retrieve_history_clamp_from_scene, retrieve_standard_clamp_from_scene, retrieve_standard_clamp_oss_address_from_scene, retrieve_history_clamp_oss_address_from_scene, \
    retrieve_standard_clamp_by_history_clamp, retrieve_history_clamp_from_scene_v2, retrieve_standard_clamp_from_scene_v2
from background.background_update import update_06
from cache.redis_pool import get_redis
from models.queryModels import CreateScene, MultipleConditionQueryTrainingData, UpdateScene
from utils.mongo_tools import delete_mongo_value, retrieve_one_mongo_value, retrieve_mongo_values, \
    retrieve_all_mongo_values, update_mongo_value, create_one_mongo_value
from views.configs import *
from views.crud import create_scene, keyword_search_scene, separate_page

deprecated_scene_router = APIRouter(
    prefix="/api/scene",
    tags=["scene"],
)


@deprecated_scene_router.get("/v1/clamp_list")
async def clamp_list(sceneNumber: str):
    """
    ## Deprecated.

    - :param queryModel:
    - :return:
    """
    model = {
        "data": {
            "result": {
                "historyClamp": [],
                "standardClamp": [],
            },
            "historyClampQuantity": 0,
            "standardClampQuantity": 0,
        },
    }
    scene = retrieve_one_mongo_value(sceneNumber, database_name=MONGO_DATABASE_NAME, collection_name=SCENE_COLLECTION)[0]

    try:
        model["data"]["result"]["historyClamp"] = retrieve_history_clamp_from_scene(scene)
        # 这个判断不能少，因为historyClamp列表里有的夹具编号不一定在数据库里有
        if len(model["data"]["result"]["historyClamp"]) > 0:
            model["data"]["historyClampQuantity"] = len(model["data"]["result"]["historyClamp"])
    except TypeError:
        pass

    try:
        model["data"]["result"]["standardClamp"] = retrieve_standard_clamp_from_scene(scene)
        if len(model["data"]["result"]["standardClamp"]) > 0:
            model["data"]["standardClampQuantity"] = len(model["data"]["result"]["standardClamp"])
    except TypeError:
        pass

    model["status"] = 1
    return model


@deprecated_scene_router.delete("/v1/history_clamp")
async def delete_history_clamp(request: Request, sceneNumber: str, historyClampNumber: str):
    """
    Deprecated.
    删除场景里的一套历史夹具，注意不是删除夹具信息，而是把它从场景里移除。

    - :param number:
    - :return:
    """
    scene = retrieve_all_mongo_values(
        {"number": sceneNumber},
        database_name=MONGO_DATABASE_NAME,
        collection_name=SCENE_COLLECTION,
    )[0]
    scene["historyClamp"].remove(historyClampNumber)

    await request.app.state.redis.set(scene["number"], json.dumps(scene))

    updateInfo = {"$set": scene}
    update_mongo_value(
        {"number": sceneNumber},
        updateInfo,
        database_name=MONGO_DATABASE_NAME,
        collection_name=SCENE_COLLECTION,
    )
    model = {"data": True, "status": 1}
    return model


@deprecated_scene_router.post("/v2/scenes")
async def multiple_condition_query_v2(request: Request, queryModel: MultipleConditionQueryTrainingData):
    """
    列表查询多条训练数据（场景）。输入参数所有字段均可为空。

    - :param queryModel:
    - :return:
    """
    model = {"data": {"result": [], "historyClampQuantity": 0, "standardClampQuantity": 0, }}

    result = []
    # 先把redis中的符合的scene key都拿出来
    scene_number_list = await request.app.state.redis.get("scene")
    scene_number_list = json.loads(scene_number_list)
    # 用上面的number列表去redis中查询所有scene
    for i in scene_number_list:
        temp_item = await request.app.state.redis.get(i)
        if temp_item is None:
            # 去mongo中查询这个id的数据
            temp_result = retrieve_one_mongo_value(i, database_name=MONGO_DATABASE_NAME, collection_name=SCENE_COLLECTION)
            # 如果mongo里能查到这条数据再把它更新到redis中
            if len(temp_result) > 0:
                temp_item = temp_result[0]
                # 把mongo中查到的数据set到redis数据库中
                await request.app.state.redis.set(temp_item["number"], json.dumps(temp_item))
            else:
                # 若是走到这一步那说明不但redis里没有，连mongo里面也没有这个number的数据了，就跳过append吧
                continue
        else:
            temp_item = json.loads(temp_item)
        result.append(temp_item)

    result = sorted(result, key=lambda x: int(x["name"]))
    result = keyword_search_scene(queryModel, result)
    model["data"]["total"] = len(result)
    if len(result) > 0:

        for i in result:
            if "history" in i.keys():
                history_clamp_quantity = len(i["historyClamp"])
                model["data"]["historyClampQuantity"] += history_clamp_quantity

            if "standard" in i.keys():
                standard_clamp_quantity = len(i["standardClamp"])
                model["data"]["standardClampQuantity"] += standard_clamp_quantity

        if not queryModel.isTotal:
            model["data"]["result"] = separate_page(result, page=queryModel.page, pagesize=queryModel.pagesize)
        else:
            model["data"]["result"] = result
    model["status"] = 1
    return model


@deprecated_scene_router.post("/v1/scene")
async def create(queryModel: CreateScene):
    """
    新增一条训练场景的完整信息

    - :param queryModel: 创建数据用的类，其中historyClamp和standardClamp可以为空，场景名称、描述和焊点是必填的。
    - :return: 创建好的完整信息也返回给前端。
    """
    model = {"data": {}}
    original_data = create_scene(
        name=queryModel.name,
        desc=queryModel.desc,
        rpsNumber=queryModel.rpsNumber,
    )
    create_one_mongo_value(
        original_data,
        database_name=MONGO_DATABASE_NAME,
        collection_name=SCENE_COLLECTION,
    )
    original_data.pop("_id")
    model["data"] = original_data
    model["status"] = 1
    return model


@deprecated_scene_router.get("/v1/scene")
async def retrieve(number: str):
    """
    返回一条训练场景的完整信息
    TODO: 其实是给前端用来下载里面的夹具压缩包用的

    - :param number: 编号
    - :return:
    """
    model = {"data": {}}
    original_data = retrieve_one_mongo_value(number, database_name=MONGO_DATABASE_NAME, collection_name=SCENE_COLLECTION)
    try:
        model["data"] = original_data[0]
        model["data"]["standardClamp"] = []
        standard_clamp_list = []
        for i in model["data"]["historyClamp"]:
            standard_clamp = retrieve_standard_clamp_by_history_clamp(i)
            if len(standard_clamp) > 0:
                standard_clamp_list.append(standard_clamp)
        model["data"]["standardClamp"] = list(set(standard_clamp_list))
        model["status"] = 1
    except IndexError:
        model["status"] = 0
    return model


@deprecated_scene_router.get("/v2/scene")
async def retrieve_by_scene_name(request: Request, name: str):
    """
    Deprecated.
    返回一条训练场景的完整信息

    - :param number: 编号
    - :return:
    """
    model = {"data": {}}
    original_data = retrieve_all_mongo_values({"name": name}, database_name=MONGO_DATABASE_NAME, collection_name=SCENE_COLLECTION)

    try:
        model["data"] = original_data[0]
        model["data"]["standardClamp"] = []
        for i in model["data"]["historyClamp"]:
            try:
                history_clamp = await request.app.state.redis.get(i)
                history_clamp = json.loads(history_clamp)
            except:
                history_clamp = retrieve_one_mongo_value(i, database_name=MONGO_DATABASE_NAME, collection_name=HISTORY_CLAMP_COLLECTION)[0]
            try:
                if len(history_clamp["related"]["standardClamp"]) > 0:
                    model["data"]["standardClamp"].append(history_clamp["related"]["standardClamp"])
            except:
                continue
        model["status"] = 1
    except IndexError:
        model["status"] = 0
    return model


@deprecated_scene_router.put("/v1/scene")
async def update(request: Request, queryModel: UpdateScene):
    """
    修改训练数据（场景）的属性

    - :param queryModel: 要更新的场景信息，其中number是必填的
    - :return:
    """
    scene = retrieve_all_mongo_values(
        {"number": queryModel.number},
        database_name=MONGO_DATABASE_NAME,
        collection_name=SCENE_COLLECTION,
    )[0]
    if queryModel.name is not None:
        scene['name'] = queryModel.name
    if queryModel.desc is not None:
        scene['desc'] = queryModel.desc
    if queryModel.rpsNumber is not None:
        scene['rpsNumber'] = queryModel.rpsNumber
    if queryModel.historyClamp is None or len(queryModel.historyClamp) > 0:
        scene['historyClamp'] = queryModel.historyClamp
    if queryModel.standardClamp is None or len(queryModel.standardClamp) > 0:
        scene['standardClamp'] = queryModel.standardClamp

    await request.app.state.redis.set(scene["number"], json.dumps(scene))

    updateInfo = {"$set": scene}
    update_mongo_value(
        {"number": queryModel.number},
        updateInfo,
        database_name=MONGO_DATABASE_NAME,
        collection_name=SCENE_COLLECTION,
    )
    model = {"data": True, "status": 1}
    return model


@deprecated_scene_router.delete("/v1/scene")
async def delete(number: str):
    """
    根据训练场景的编号删除训练场景（一次删除单条数据）

    - :param number:
    - :return:
    """
    model = {"data": False}
    try:
        result = delete_mongo_value(
            number=number,
            database_name=MONGO_DATABASE_NAME,
            collection_name=SCENE_COLLECTION
        )
        if result.deleted_count > 0:
            model["data"] = True
            model["status"] = 1
        else:
            model["status"] = 0
    except:
        model["status"] = 0
    return model


@deprecated_scene_router.post("/v1/scenes")
async def multiple_condition_query(request: Request, queryModel: MultipleConditionQueryTrainingData):
    """
    列表查询多条训练数据（场景）。输入参数所有字段均可为空。

    - :param queryModel:
    - :return:
    """
    model = {"data": {"result": [], "historyClampQuantity": 0, "standardClampQuantity": 0, }}

    result = []
    # 先把redis中的符合的scene key都拿出来
    scene_number_list = await request.app.state.redis.get("scene")
    scene_number_list = json.loads(scene_number_list)
    # 用上面的number列表去redis中查询所有scene
    for i in scene_number_list:
        temp_item = await request.app.state.redis.get(i)
        if temp_item is None:
            # 去mongo中查询这个id的数据
            temp_result = retrieve_one_mongo_value(i, database_name=MONGO_DATABASE_NAME, collection_name=SCENE_COLLECTION)
            # 如果mongo里能查到这条数据再把它更新到redis中
            if len(temp_result) > 0:
                temp_item = temp_result[0]
                # 把mongo中查到的数据set到redis数据库中
                await request.app.state.redis.set(temp_item["number"], json.dumps(temp_item))
            else:
                # 若是走到这一步那说明不但redis里没有，连mongo里面也没有这个number的数据了，就跳过append吧
                continue
        else:
            temp_item = json.loads(temp_item)
        result.append(temp_item)

    result = sorted(result, key=lambda x: int(x["name"]))
    result = keyword_search_scene(queryModel, result)
    model["data"]["total"] = len(result)
    if len(result) > 0:

        if not queryModel.isTotal:
            result = separate_page(result, page=queryModel.page, pagesize=queryModel.pagesize)
        else:
            result = result

        for i in result:
            history_clamp_quantity = len(i["historyClamp"])
            model["data"]["historyClampQuantity"] += history_clamp_quantity
            if history_clamp_quantity > 0:
                for j in i["historyClamp"]:
                    try:
                        standard_clamp = get_standard_clamp_by_history_clamp(j)
                    except:
                        history_clamp = retrieve_one_mongo_value(j, database_name=MONGO_DATABASE_NAME, collection_name=HISTORY_CLAMP_COLLECTION)
                        if len(history_clamp) > 0:
                            history_clamp = history_clamp[0]
                            await request.app.state.redis.set(history_clamp["number"], history_clamp)
                        else:
                            continue
                        standard_clamp = history_clamp["related"]["standardClamp"]
                    #     TODO：20210506晚上做到这里
                    if len(standard_clamp) > 0:
                        i["standardClamp"].append(standard_clamp)
                i["standardClamp"] = list(set(i["standardClamp"]))
            standard_clamp_quantity = len(i["standardClamp"])
            model["data"]["standardClampQuantity"] += standard_clamp_quantity

        model["data"]["result"] = result
    model["status"] = 1
    return model
